#include <iostream>
// OS
#include <pthread.h>
#include <unistd.h>

namespace ThreadMoudle
{
    typedef void *(*func_t)(std::string &);//线程运行函数类型

    class myThread
    {
    public:
        void Execute()
        {
            std::cout << "new mythread running... name:" << _name << std::endl;
            _isrunning = true;
            _func(_name);
            _isrunning = false;
        }

    public:
        myThread(std::string name, func_t func)
            : _name(name), _func(func)
        {
            std::cout << "new myThread create success, name:" << name << std::endl;
        }
        static void *ThreadRoutine(void *args)
        {
            //((myThread*)args)->_func(((myThread*)args)->_name);//方法一
            myThread *self = static_cast<myThread *>(args);
            self->Execute(); // self->_func(self->_name);
            return nullptr;
        }
        bool Start()
        {
            int n = pthread_create(&_tid, nullptr, ThreadRoutine, (void *)this);
            if (n != 0)
            {
                perror("pthread_create fail");
                return false;
            }
            return true;
        }
        void Join()
        {
            void *result = nullptr;
            int n = pthread_join(_tid, &result);
            if (n != 0)
            {
                perror("pthread_join fail");
            }
            std::cout << "wait new myThread success, name:" << _name << std::endl;
        }
        std::string Stat()
        {
            if (_isrunning)
                return "running";
            else
                return "sleep";
        }
        void Stop()
        {
            if (_isrunning)
            {
                pthread_cancel(_tid); // 取消指定线程
                _isrunning = false;
                std::cout << _name << " stop" << std::endl;
            }
        }
        std::string Name()
        {
            return _name;
        }
        ~myThread()
        {
        }

    private:
        std::string _name;
        pthread_t _tid;
        func_t _func;
        bool _isrunning;
    };
};
